<?php

namespace App\Library\Logic;

use App\Library\Lock;
use App\Library\Requests\Amount\AmountPageRequest;
use App\Models\AmountModel;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;

class AmountLogic extends AmountModel
{
    /**
     * insertForModelOfLock
     * @param array $data
     * @return Model
     */
    public static function insertForModelOfLock(array $data): Model
    {
        return Lock::get($data['userId'] . __CLASS__ . __FUNCTION__, function () use ($data) {
            $data['balance'] = bcadd(self::balanceOfLock($data['userId']), $data['amount'], 2);
            $userType = ShopUserLogic::valueByWhere('userId', $data['userId'], 'user_type');
            $data['userTypeId'] = $userType ?? 0;
            return self::insertForModel($data);
        });
    }

    /**
     * balanceOfLock
     * @param int|null $userId
     * @return mixed
     */
    public static function balanceOfLock(int $userId = null): float
    {
        return Lock::get($userId . __CLASS__ . __FUNCTION__, function () use ($userId) {
            return self::balance($userId);
        });
    }

    /**
     * balance
     * @param int|null $userId
     * @return float
     */
    public static function balance(int $userId = null): float
    {
        return self::query()->where('user_id', $userId ?? USERID)->sum('amount');
    }

    /**
     * 总收入
     * @return int|mixed
     *
     */
    public function totalIncome(AmountPageRequest $request): mixed
    {
        $builder = self::query()->where('user_id', USERID);

        if (!is_null($request->startAt)) $builder->whereBetween('created_at', [
            now()->parse($request->startAt)->startOfMonth(),
            now()->parse($request->startAt)->endOfMonth()
        ]);

        return $builder->whereIn('type', [
            'adjustment',
            'order',
            'box',
            'ticket',
            'invite',
            'auction'
        ])->sum('amount');
    }

    /**
     * 已打款
     * @return int|mixed
     *
     */
    public function withdraw(AmountPageRequest $request = null): mixed
    {
        $builder = self::query()->where([
            'user_id' => USERID,
            'status' => 1,
            'type' => 'withdraw'
        ]);
        if (!is_null($request) && !is_null($request->startAt)) $builder->whereBetween('created_at', [
            now()->parse($request->startAt)->startOfMonth(),
            now()->parse($request->startAt)->endOfMonth()
        ]);

        return $builder->sum('amount');
    }

    /**
     * 记录
     * @param AmountPageRequest $request
     * @return array
     *
     */
    public function paging(AmountPageRequest $request): array
    {
        $builder = self::query()
            ->where('user_id', USERID);
        if (!is_null($request->startAt)) $builder->whereBetween('created_at', [
            now()->parse($request->startAt)->startOfMonth(),
            now()->parse($request->startAt)->endOfMonth()
        ]);
        return paginate($builder->orderByDesc('created_at')->paginate($request->limit));
    }

    /**
     *
     * @param int|null $userId
     * @return mixed
     *
     */
    public static function entered(int $userId = null): mixed
    {
        return self::query()->where('user_id', USERID)->value('balance');
    }

    /**
     * insertForModelOfLock
     * @param Model $order
     * @return Model
     */
    public static function plug(Model $order): Model
    {
        return self::insertForModelOfLock([
            'type' => 'order',
            'title' => '订单支付',
            'userId' => USERID,
            'objectType' => $order->getTable(),
            'objectId' => $order->order_id,
            'amount' => -$order->pay_price,
        ]);
    }

    /**
     * insertForModelOfLock
     * @param Model $model
     * @param mixed $refund
     * @return Model
     */
    public static function plugReturn(Model $model, mixed $refund): Model
    {
        $where = [
            'type' => 'order',
            'title' => '订单退款',
            'userId' => $model->buy_user_id,
            'objectType' => $model->order->getTable(),
            'objectId' => $model->order_id,
            'amount' => $refund,
        ];
        if ($amount = self::findByWhere($where)) return $amount;
        else return self::insertForModelOfLock($where);
    }
}
